package com.example.kotlincoroutine

import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.junit.Test
import java.io.BufferedReader
import java.io.FileReader

class CoroutineTest03 {

    //把函数变成协程到方式用runBlocking
    @Test
    fun `test release resources`() = runBlocking<Unit> {//如果没有阻塞，那么就要返回runBlocking<Unit>
        val job = launch {
            try {
                //1000个协程
                repeat(1000) { i ->
                    println("job sleeping")
                    delay(500L)
                }
            } catch (e: Exception) {

            } finally {
                //在这里释放资源
                println("job: finally")
            }
        }
        delay(1300)
        println("main: im` tired of waiting")
        job.cancelAndJoin()
        println("main: im` quit")
    }

    @Test
    fun `test use function`() = runBlocking<Unit> {//如果没有阻塞，那么就要返回runBlocking<Unit>
        //use 函数只能被实现了Closeable的对象使用，程序结束时会自动调用close方法，适合文件对象
//        val br = BufferedReader(FileReader("/Users/huliangyuan/fanbianyi/mdd/temp/readme.txt"))
//        with(br) {
//            try {
//                var line: String?
//                while (true) {
//                    line = readLine() ?: break
//                    println(line)
//                }
//            } finally {
//                close()
//            }
//        }
//        if (File("/Users/huliangyuan/fanbianyi/mdd/temp/p.java").exists()) {
//            println("存在啊")
//        }
//        println(FileReader(File("/Users/huliangyuan/fanbianyi/mdd/temp/p.java")).readLines())
        BufferedReader(FileReader("/Users/huliangyuan/fanbianyi/mdd/temp/p.java")).use {
            var line: String?
            while (true) {
                line = it.readLine() ?: break
                println(line)
            }
        }
    }

    @Test
    fun `test use NonCancellable`() = runBlocking<Unit> {//如果没有阻塞，那么就要返回runBlocking<Unit>
        //演示协程取消时，异常出现后，finally的代码可以继续执行挂起函数后面的代码，需要使用协程切换到不可取消上面去
        val job = launch {
            try {
                //1000个协程
                repeat(1000) { i ->
                    println("job sleeping")
                    delay(500L)
                }
            } catch (e: Exception) {

            } finally {
                //在这里释放资源
//                println("job: finally")
//                delay(1000)
//                println("job: finally 一般这里的不会执行")//一般这里的不会执行
                withContext(NonCancellable){
                    println("job: finally")
                    delay(1000)
                    println("job: finally这样可以执行")//这样可以执行
                }
            }
        }
        delay(1300)
        println("main: im` tired of waiting")
        job.cancelAndJoin()
        println("main: im` quit")
    }
}